% Ark TS Code Auditor to DevEco Conversion
% James Cordy et al., Huawei Technologies
% December 2023 (Rev. Dec 2023)

% Audit comment grammar
define audit_comment
    '/* 'HPAudit: [hpaudit_message] : [hpaudit_code] : [severity] : [line_number] : [file_path] '*/ [NL]
end define

define file_path
    [disk_colon?] [not_space_colon] [not_space_colon*]
end define

define disk_colon
    [id] :
end define

define not_space_colon
    [not ':] [token]
end define

define line_number
    [number]
end define

define hpaudit_code
    [not_space_colon] [SPOFF] [not_space_colon*] [SPON]
end define

define hpaudit_message
    [not_space_colon] [not_space_colon*]
end define

define severity
    [number]
end define

% JSON grammar
define json_list
    '[ [IN][NL] [list json_group] [EX][NL] ']
end define

define json_group
    '{ [IN] [list json_property] [EX][NL]'}
end define

define json_property
    [NL] [json_key] : [json_value]
end define

define json_key
    [stringlit]
end define

define json_value
    [stringlit] | [number] | [id] | [json_list]
end define

% Island grammar for input
define program
    [island_or_water*]
end define

define island_or_water
        [audit_comment]
    |   [water]
end define

define water
    [drop+]
end define

define drop
    [not audit_comment] [token]
end define

% We're converting to JSON
redefine program
        ...
    |   [json_list]   
end define

% Convert HPAudit comments to DevEco JSON report format
function main
    % Input is audited TS code with embedded HPAudit comments
    replace [program]
        IslandsAndWater [island_or_water*]
    % We're only interested in the HPAudit comment islands
    construct Islands [island_or_water*]
        IslandsAndWater [removeWater]
    % Get the file path from the first HPAudit comment island
    deconstruct * [file_path] Islands
        FilePath [file_path]
    construct FilePathString [stringlit]
        _ [quote FilePath]
    % Convert each HPAudit comment to DevEco JSON report format
    construct HPAuditIssues [list json_group]
        _ [makeHPAuditIssue each Islands]
    % Make JSON report
    construct JSON [json_list]
        '[ '{
            "filePath" : FilePathString,
            "defects" : '[ HPAuditIssues ']
        '} ']
    by
        JSON
end function

% Remove everything but HPAudit comments from the input
rule removeWater
    replace [island_or_water*]
        _ [water]
        More [island_or_water*]
    by
        More
end rule

% Convert each HPAudit comment to DevEco JSON report format
function makeHPAuditIssue Island [island_or_water]
    % Get the line number, description and ruleid from the HPAudit comment
    deconstruct Island
        '/* 'HPAudit: HPAuditMessage [hpaudit_message] : HPAuditCode [hpaudit_code] : Severity [number] : LineNumber [number] : FilePath [file_path] '*/ 
    deconstruct LineNumber
        ReportLine [number]
    construct Description [stringlit]
        _ [quote HPAuditMessage]
    construct RuleId [stringlit]
        _ [quote HPAuditCode] 
    % Is it automatically fixable?
    construct False [id]
        'false
    construct Fixable [id]
        False [orFixed Description]
    % Add this report item to the list
    replace * [list json_group]
    by
      '{
        "reportLine": ReportLine,
        "reportColumn": 1,
        "description": Description,
        "severity": Severity,
        "ruleId": RuleId,
        "mergeKey": "",
        "category": "",
        "ruleDocPath": "",
        "fixable": Fixable,
        "fixKey": ""
      '}
end function

% Is it automatically fixable?
function orFixed Description [stringlit]
    where 
        Description [grep "(fixed)"]
    replace [id]
        'false
    by
        'true
end function
